﻿@page "/servers"
@inject INodeService iNodeService
@implements IDisposable

<Table TItem="Node"
       DataSource="@data"
       @bind-PageIndex="pagination.page"
       @bind-PageSize="pagination.rows"
       Total="pagination.records"
       OnExpand="OnRowExpand"
       Loading="_loading" OnChange="HandleTableChange" RemoteDataSource>

    <RowTemplate>
        <Column @bind-Field="@context.IP" Style="text-align:center">
            <Tag>@context.IP</Tag>
        </Column>
        <Column TData="int" Title="Status">
            @if (context.Status == 2)
            {
                <Badge Status="success" /> <i>Running</i>
            }
            else if (context.Status == 4)
            {
                <Badge Status="error" /> <i>Stopped</i>
            }
        </Column>
        <Column TData="string" Title="CPU" Style="text-align:center">
            <Progress Type=ProgressType.Circle Percent="@(Math.Round(double.Parse(context.CPU?.TrimEnd('%') ?? "0"),2))" Size="@ProgressSize.Small" StrokeColor=_gradients />
        </Column>
        <Column TData="string" Title="MEM" Style="text-align:center">
            <Progress Type=ProgressType.Circle Percent="@Math.Round(double.Parse(context.MEM?.TrimEnd('%') ?? "0"),2)" Size="@ProgressSize.Small" StrokeColor=_gradients />
            <div style="margin-top:10px">
                <i>@context.MEMUSAGEString/@context.MEMTOTALString</i>
            </div>
        </Column>
        <Column @bind-Field="@context.BLOCKIO" Style="text-align:center">
            <Progress Type=ProgressType.Circle Percent="@Math.Round(double.Parse(context.BLOCKIO?.TrimEnd('%') ?? "0"),2)" Size="@ProgressSize.Small" StrokeColor=_gradients />
            <div style="margin-top:10px">
                <i>@context.BLOCKIOUSAGE/@context.BLOCKIOTOTAL</i>
            </div>
        </Column>
        <Column @bind-Field="@context.LastActiveTime" Style="text-align:center"></Column>
        <ActionColumn Title="Operation" Width="200" Style="text-align:center">
            <Space Size=@("middle")>
                @if (context.Status != 4)
                {
                    <SpaceItem>
                        <Button Type="@ButtonType.Link" OnClick="_ => EditItem(context)">
                            Create Service
                        </Button>
                    </SpaceItem>
                }
            </Space>
        </ActionColumn>
    </RowTemplate>

    <ExpandTemplate>
        @*Size=@TableSize.Small*@
        <div class="ExpandTemplateTable">
            <Table Context="service" TItem="ServiceInstance" DataSource="@context.Data.ServiceInstances" Class="ExpandTemplateTable" HidePagination>
                <Column TData="string" DataIndex="Title">
                    <Tag Color="#55acee">@service.Title</Tag>
                </Column>
                <Column TData="int" Title="Port">
                    @if (service.Port == 0)
                    {
                        if (service.Title == "iTool-FileApi")
                        {
                            <Tag>1996</Tag>
                        }
                        else
                        {
                            <Tag>iToolPort</Tag>
                        }
                    }
                    else
                    {
                        <Tag>@service.Port</Tag>
                    }
                </Column>
                <Column TData="string" Title="Cpu" Width="100">
                    <Progress Percent="@Math.Round(double.Parse(service?.Cpu?.TrimEnd('%') ?? "0"),2)" Size="@ProgressSize.Small" StrokeColor=_gradients />
                </Column>
                <Column TData="int" Title="Status">
                    @if (service?.Status == 2)
                    {
                        <Badge Status="success" /> <i>Running</i>
                    }
                    else if (service?.Status == 3)
                    {
                        <Badge Status="processing" /> <i>ReStarting</i>
                    }
                    else if (service?.Status == 4)
                    {
                        <Badge Status="error" /> <i>Stopped</i>
                    }
                    else if (service?.Status == 5 || service?.Status == 6)
                    {
                        <Badge Status="processing" /> <i>Not available</i>
                    }
                    else if (service?.Status == 11)
                    {
                        <Badge Status="processing" /> <i>Waiting Stop Signal</i>
                    }
                    else if (service?.Status == 12)
                    {
                        <Badge Status="processing" /> <i>Waiting Start Signal</i>
                    }
                </Column>

                <Column TData="string" Title="Memory">
                    <Tag Color="#87d068">@service.Memory</Tag>
                </Column>

                <Column TData="int" Title="User">
                    @if (string.IsNullOrWhiteSpace(service?.User) & string.IsNullOrWhiteSpace(service?.Password))
                    {
                        <Tag>not enabled</Tag>
                    }
                    else if (string.IsNullOrWhiteSpace(service?.User))
                    {
                        <Tag Icon="lock" Color="#f50">@service?.Password</Tag>
                    }
                    else
                    {
                        <Tag Icon="user" Color="blue-inverse">@service?.User</Tag>
                        <Tag Icon="lock" Color="#f50">@service?.Password</Tag>
                    }
                </Column>

                <Column TData="string" Title="Database(s)">
                    @if (service.Process == "SqlServer" && !string.IsNullOrWhiteSpace(service.Type))
                    {
                        foreach (var item in service.Type?.Split(','))
                        {
                            <Tag Color="#55acee">@item</Tag>
                        }
                    }
                    else
                    {
                        <Tag>NULL</Tag>
                    }
                </Column>

                @*<Column @bind-Field="@service.IsRunInDocker"></Column>*@
                <Column @bind-Field="@service.LastCheckTime" Width="160"></Column>

                <ActionColumn Title="Operation" Width="300">
                    <Space>
                        <Dropdown Trigger="@(new AntDesign.Trigger[] { Trigger.Click })" Placement="@Placement.BottomLeft">
                            <Overlay>
                                <Menu>
                                    <MenuItemGroup Title=@("Excuter")>
                                        @if (service.Status == 2)
                                        {
                                            <MenuItem>
                                                <Button Type="@ButtonType.Link" Danger OnClick="@(async () => { await OperationConfrim(context.Data, service, 4); })">
                                                    Stop
                                                </Button>
                                            </MenuItem>
                                        }
                                        else if (service.Status == 4)
                                        {
                                            <MenuItem>
                                                <Button Type="@ButtonType.Link" OnClick="@(async () => { await OperationConfrim(context.Data, service, 1); })">
                                                    Start
                                                </Button>
                                            </MenuItem>
                                        }

                                        @if (service.IsRunInDocker)
                                        {
                                            <MenuItem>
                                                <Button Type="@ButtonType.Link" OnClick="@(async () => { await OperationConfrim(context.Data, service, 2); })">
                                                    Backup
                                                </Button>
                                            </MenuItem>
                                            <MenuItem>
                                                <Button Type="@ButtonType.Link" Danger OnClick="@(async () => { await OperationConfrim(context.Data, service, 5); })">
                                                    Clear And Delete
                                                </Button>
                                            </MenuItem>
                                        }

                                        <MenuItem>
                                            <Button Type="@ButtonType.Link" OnClick="@(async () => { await OperationConfrim(context.Data, service, 3); })">
                                                ReStart
                                            </Button>
                                        </MenuItem>
                                    </MenuItemGroup>

                                    @if (service.Process == "SqlServer" && service.Status == 2)
                                    {
                                        <MenuItemGroup Title=@("Database")>
                                            <MenuItem>
                                                <Button Type="@ButtonType.Link" OnClick="@(async () => { await OperationConfrim(context.Data, service, 6); })">
                                                    Create iTool Database
                                                </Button>
                                            </MenuItem>
                                        </MenuItemGroup>
                                        @if (service.Process == "SqlServer" && !string.IsNullOrWhiteSpace(service.Type))
                                        {
                                            <MenuItemGroup Title=@("Drop")>
                                                @foreach (var item in service.Type?.Split(','))
                                                {
                                                    <MenuItem>
                                                        <Button Type="@ButtonType.Link" Danger OnClick="@(async () => { await OperationConfrim(context.Data, service, 7, item); })">
                                                            @item
                                                        </Button>
                                                    </MenuItem>
                                                }
                                            </MenuItemGroup>
                                        }
                                    }
                                </Menu>
                            </Overlay>
                            <ChildContent>
                                <a @onclick:preventDefault>
                                    Operation menu <Icon Type="down" />
                                </a>
                            </ChildContent>
                        </Dropdown>
                    </Space>
                </ActionColumn>
            </Table>
        </div>
    </ExpandTemplate>

</Table>


@*服务管理*@
<Drawer Closable="true" Width="800" Visible="visible" Title='("服务管理")' OnClose="_ => closeDrawer()">
    <Template style="height:90%">
        <Form Model="@serviceOptions"
              LabelColSpan="8"
              WrapperColSpan="16"
              Size="@AntSizeLDSType.Default">

            @foreach (var item in context.Services)
            {
                <FormItem Label="@item.GetType().Name">

                    @if (new string[] { "iToolService", "iToolClient", "iToolFileCenter" }.Contains(item.GetType().Name))
                    {
                        <Button Type="primary" Size="small" Disabled="@(nodeitem?.ServiceInstances.Any(s => s.Process == item.GetType().Name) == true || !item.IsCreate)" Loading="item.IsStartCreate" OnClick="_ => CreateiToolService(item)">
                            创建实例
                        </Button>

                        if (nodeitem?.ServiceInstances.Any(s => s.Process == item.GetType().Name) == true)
                        {
                            <Alert Message="@("实例已经创建")" Type="@AlertType.Error" Style="margin-top:15px" />
                        }
                    }
                    else
                    {
                        <Button Type="primary" Size="small" Disabled="@(!item.IsCreate)" OnClick="_ => CreateInstInstance(item)">
                            配置实例
                        </Button>
                    }

                    @if (!string.IsNullOrWhiteSpace(item.IsNoCreateMessage))
                    {
                        @foreach (var message in item.IsNoCreateMessage.Split(','))
                        {
                            if (message == "Not iToolService" || message == "Not Set iToolCenter" || message.IndexOf("SqlServer") > -1)
                            {
                                <Alert Message="@message" Type="@AlertType.Error" Style="margin-top:15px" />
                            }
                            else
                            {
                                <Alert Message="@message" Type="@AlertType.Error" Style="margin-top:15px" CloseText="Create Now" Closable OnClose="_ => MessageCloseTriggerCreate(message)" />
                            }
                        }
                    }
                </FormItem>
            }

            <Drawer Width="600" Closable="true" Visible="@serviceInstance.OpenDrawerEnable" Title="@serviceInstance.GetType().Name" OnClose="_ => CloseCreateInstInstance()">
                <Form Model="@serviceInstance"
                      Context="service"
                      LabelColSpan="8"
                      WrapperColSpan="16"
                      OnFinish="SubmitCreateInstInstance"
                      Size="@AntSizeLDSType.Small">

                    <FormItem Label="Title">
                        <Input @bind-Value="@service.ServiceInstance.Title" />
                    </FormItem>

                    <FormItem Label="Port">
                        <Input @bind-Value="@service.ServiceInstance.Port" />
                    </FormItem>

                    @if (service.FromConfig.User)
                    {
                        <FormItem Label="User">
                            <Input @bind-Value="@service.ServiceInstance.User" />
                        </FormItem>
                    }

                    @if (service.FromConfig.Password)
                    {
                        <FormItem Label="Password">
                            <Input @bind-Value="@service.ServiceInstance.Password" />
                        </FormItem>
                    }

                    <FormItem WrapperColOffset="8" WrapperColSpan="16">
                        <Button HtmlType="submit" Loading="service.ServiceInstance.Status == 1" Disabled="service.ServiceInstance.Status == 2">
                            开始创建
                        </Button>
                    </FormItem>
                </Form>
            </Drawer>

        </Form>
    </Template>

</Drawer>

@*数据库创建*@
<Drawer Closable="true" Width="400" Visible="visibleCreateDatabase" Title='("iTool默认运行时数据库创建")' OnClose="_ => closeDrawer()">
    <Template style="height:90%">
        <Form Model="@serviceInstanceRow"
              LabelColSpan="8"
              Context="serviceRow"
              WrapperColSpan="16"
              Size="@AntSizeLDSType.Default">

            <AntDesign.CheckboxGroup Options="@ckeckAllOptions" />

            <FormItem WrapperColOffset="1" WrapperColSpan="16" Style="margin-top:20px">
                <Button HtmlType="submit" Loading="serviceRow.Status == 1" OnClick="_ => CreateiToolDatabase()">
                    开始创建
                </Button>
            </FormItem>

        </Form>
    </Template>

</Drawer>



@code {
    WindowsHelper windows;
    Node nodeitem;
    DrawerServiceOptions serviceOptions = new DrawerServiceOptions();

    private Dictionary<string, string> _gradients = new Dictionary<string, string>()
{
        { "0%", "#87d068" },
        { "40%", "#87d068" },
        { "70%", "#ff7875" },
        { "99%", "#ff1818" }
    };

    SqlServer baseSqlServer = new SqlServer
    {
        ServiceInstance = new ServiceInstance()
    };

    AbstractServer serviceInstance;

    Core.DataAccess.Model.Pagination pagination = new Core.DataAccess.Model.Pagination
    {
        page = 1,
        rows = 7
    };

    int _reloadpercent = 0;
    bool _loading = false;
    bool visible = false;
    bool visibleCreateDatabase = false;


    List<Node> data;
    private System.Timers.Timer iTimer;

    protected override void OnInitialized()
    {
        serviceInstance = baseSqlServer;
    }


    public void Dispose()
    {
        if (this.iTimer != null)
        {
            this.iTimer.Stop();
            this.iTimer = null;
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            windows = new WindowsHelper(jSRuntime);
            await this.LoadData();

            await windows.HideLoadingAsync();

            iTimer = new System.Timers.Timer();
            iTimer.Elapsed += new System.Timers.ElapsedEventHandler((sender, args) => this.TimerMethod());
            iTimer.Interval = 5000;
            iTimer.AutoReset = true;
            iTimer.Enabled = true;

        }
    }

    public async void TimerMethod()
    {
        await this.LoadData(true);

    }

    private async Task LoadData(bool isTimer = false)
    {
        await base.InvokeAsync(async () =>
        {
            if (isTimer)
            {
                var nodes = await this.iNodeService.GetNodes(pagination);

                try
                {
                    foreach (var itemNode in nodes)
                    {
                        foreach (var item in this.data)
                        {
                            if (item.NodeId == itemNode.NodeId)
                            {
                                item.BLOCKIO = itemNode.BLOCKIO;
                                item.BLOCKIOTOTAL = itemNode.BLOCKIOTOTAL;
                                item.BLOCKIOUSAGE = itemNode.BLOCKIOUSAGE;
                                item.CPU = itemNode.CPU;
                                item.MEM = itemNode.MEM;
                                item.MEMTOTAL = itemNode.MEMTOTAL;
                                item.MEMTOTALString = itemNode.MEMTOTALString;
                                item.MEMUSAGE = itemNode.MEMUSAGE;
                                item.MEMUSAGEString = itemNode.MEMUSAGEString;
                                item.LastActiveTime = itemNode.LastActiveTime == null ? itemNode.LastActiveTime : itemNode.LastActiveTime?.AddHours(8);

                                foreach (var service in item.ServiceInstances)
                                {
                                    foreach (var itemService in itemNode.ServiceInstances)
                                    {
                                        if (service.ServiceInstanceId == itemService.ServiceInstanceId)
                                        {
                                            service.Cpu = itemService.Cpu;
                                            service.Memory = itemService.Memory;
                                            service.Status = itemService.Status;
                                            if (service.Status == 2)
                                            {
                                                itemNode.Status = 2;
                                            }
                                            service.LastCheckTime = itemService.LastCheckTime == null ? itemService.LastCheckTime : itemService.LastCheckTime?.AddHours(8);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
            else
            {
                this._loading = true;
                this.data = await this.iNodeService.GetNodes(pagination);
                this._loading = false;
            }
            await windows.ConsoleLogAsync(this.data);
            base.StateHasChanged();
        });
    }

    private async Task HandleTableChange(QueryModel<Node> queryModel)
    {
        if (windows != null)
        {
            this.pagination.page = queryModel.PageIndex;
            this.pagination.rows = queryModel.PageSize;
            await this.LoadData();
        }
    }

    void EditItem(Node item)
    {
        this.visible = true;
        this.nodeitem = item;
        serviceOptions = new DrawerServiceOptions();
    }

    void closeDrawer()
    {
        this.visible = false;
        this.visibleCreateDatabase = false;
    }

    void CreateInstInstance(AbstractServer instance, int typeIndex = 0)
    {
        if (instance.ServiceInstance == null)
        {
            int defaultPort = 0;
            switch (instance.GetType())
            {
                case var type when type == typeof(SqlServer):
                    defaultPort = 1433;
                    break;
                //case var type when type == typeof(RabbitMQ):
                //    defaultPort = 5672;
                //    break;
                //case var type when type == typeof(Redis):
                //    defaultPort = 6379;
                //    break;
                case var type when type == typeof(MongoDB):
                    defaultPort = 27017;
                    break;
                case var type when type == typeof(Elasticsearch):
                    defaultPort = 9200;
                    break;
            }
            instance.ServiceInstance = new ServiceInstance
            {
                Title = instance.GetType().Name,
                Port = defaultPort,
                Status = 0
            };
        }
        instance.OpenDrawerEnable = true;
        serviceInstance = instance;
    }

    void CloseCreateInstInstance()
    {
        serviceInstance.ServiceInstance = null;
        serviceInstance = this.baseSqlServer;
    }


    async Task CreateiToolService(AbstractServer instance)
    {
        instance.IsStartCreate = true;

        await InvokeAsync(async () =>
        {
            string title = string.Empty;

            switch (instance.GetType().Name)
            {
                case "iToolService":
                    title = "iTool-Server";
                    break;
                case "iToolClient":
                    title = "iTool-Connector";
                    break;
                case "iToolFileCenter":
                    title = "iTool-FileApi";
                    break;
            }

            var result = await instance.Install(nodeitem, new InstallOptions
            {
                IP = nodeitem.IP,
                NodeId = nodeitem.NodeId,
                Title = title,
                Port = 0,
                databaseType = string.Empty,
                User = string.Empty,
                Password = string.Empty
            });
            instance.IsStartCreate = false;

            if (result.Item1)
            {
                var task = notice.Success(new NotificationConfig
                {
                    Message = "创建实例成功",
                    Description = result.Item2,
                    Duration = 2
                });

                this.closeDrawer();
            }
            else
            {
                var task = notice.Error(new NotificationConfig
                {
                    Message = "创建实例失败请重试",
                    Description = result.Item2,
                    Duration = 10
                });
            }

            base.StateHasChanged();
        });


    }


    async Task SubmitCreateInstInstance(EditContext editContext)
    {
        serviceInstance.ServiceInstance.Status = 1;

        await InvokeAsync(async () =>
        {

            if (string.IsNullOrWhiteSpace(serviceInstance.ServiceInstance.Title))
            {
                var task = notice.Error(new NotificationConfig
                {
                    Message = "数据验证失败",
                    Description = "Title is null"
                });
                serviceInstance.ServiceInstance.Status = 0;
                return;
            }
            else
            {
                var service = nodeitem.ServiceInstances?.Where(item => item.Title == serviceInstance.ServiceInstance.Title).FirstOrDefault();

                if (service != null)
                {
                    var task = notice.Error(new NotificationConfig
                    {
                        Message = $"进程名称已存在",
                        Description = "请重新输入 Title 信息"
                    });
                    serviceInstance.ServiceInstance.Status = 0;
                    return;
                }
            }

            if (serviceInstance.ServiceInstance.Port < 1000 || serviceInstance.ServiceInstance.Port > 65535)
            {
                var task = notice.Error(new NotificationConfig
                {
                    Message = "数据验证失败",
                    Description = "请输入1000~65535开放端口号"
                });
                serviceInstance.ServiceInstance.Status = 0;
                return;
            }
            else
            {
                var service = nodeitem.ServiceInstances?.Where(item => item.Port == serviceInstance.ServiceInstance.Port).FirstOrDefault();

                if (service != null)
                {
                    var task = notice.Error(new NotificationConfig
                    {
                        Message = $"端口号已经被 {service.Title} 占用",
                        Description = "请重新输入端口号"
                    });
                    serviceInstance.ServiceInstance.Status = 0;
                    return;
                }
            }

            if (serviceInstance.FromConfig.User && string.IsNullOrWhiteSpace(serviceInstance.ServiceInstance.User))
            {
                var task = notice.Error(new NotificationConfig
                {
                    Message = "数据验证失败",
                    Description = "User is null"
                });
                serviceInstance.ServiceInstance.Status = 0;
                return;
            }

            if (serviceInstance.FromConfig.Password)
            {

                if (serviceInstance.GetType() == typeof(MongoDB))
                {
                    var regex = new System.Text.RegularExpressions.Regex(@"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$", System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace);
                    if (!regex.IsMatch(serviceInstance.ServiceInstance.Password))
                    {
                        var task = notice.Error(new NotificationConfig
                        {
                            Message = "数据验证失败",
                            Description = "密码必须数字加大小写字母，不可包含特殊字符,并且至少8位长度！"
                        });
                        serviceInstance.ServiceInstance.Status = 0;
                        return;
                    }
                }
                else
                {
                    var valid = new iTool.ValidationExtend.PasswordAttribute();
                    if (!valid.IsValid(serviceInstance.ServiceInstance.Password))
                    {
                        var task = notice.Error(new NotificationConfig
                        {
                            Message = "数据验证失败",
                            Description = valid.ErrorMessage
                        });
                        serviceInstance.ServiceInstance.Status = 0;
                        return;
                    }
                }
            }

            var result = await serviceInstance.Install(nodeitem, new InstallOptions
            {
                IP = nodeitem.IP,
                NodeId = nodeitem.NodeId,
                databaseType = serviceInstance.ServiceInstance.Type,
                Title = serviceInstance.ServiceInstance.Title,
                Port = serviceInstance.ServiceInstance.Port,
                User = serviceInstance.ServiceInstance.User,
                Password = serviceInstance.ServiceInstance.Password
            });

            serviceInstance.OpenDrawerEnable = false;

            if (result.Item1)
            {
                var task = notice.Success(new NotificationConfig
                {
                    Message = "创建实例成功，请尝试连接",
                    Description = result.Item2,
                    Duration = 2
                });

                serviceInstance.ServiceInstance = null;
                serviceInstance = this.baseSqlServer;
            }
            else
            {
                var task = notice.Error(new NotificationConfig
                {
                    Message = "创建实例失败请重试",
                    Description = string.IsNullOrWhiteSpace(result.Item2) ? "<hr /><p>1. Title是否冲突？</><p>2. 端口是否已经被占用？</p><p>3. 账户是否不符合规定？</p>" : result.Item2,
                    Duration = 10
                });
            }

            serviceInstance.ServiceInstance.Status = 0;

            base.StateHasChanged();
        });


    }

}


@*Service*@
@code{

    ServiceInstance serviceInstanceRow = new ServiceInstance();

    CheckboxOption[] ckeckAllOptions = new CheckboxOption[]{
        new CheckboxOption{ Label="iToolBase",Value="iToolBase"},
        new CheckboxOption{ Label="Function", Value="Function" },
        new CheckboxOption{ Label="Message", Value="Message" },
        new CheckboxOption{ Label="Logger", Value="Logger"},
        new CheckboxOption{ Label="CustomData", Value="CustomData"}
    };

    async void CreateiToolDatabase()
    {

        await base.InvokeAsync(async () =>
        {

            serviceInstanceRow.Status = 1;
            base.StateHasChanged();

            var selected = ckeckAllOptions.Where(item => item.Checked && !item.Disabled);

            if (selected.Count() == 0)
            {
                var task = notice.Warning(new NotificationConfig
                {
                    Message = "操作取消",
                    Description = "没有选中任何数据库"
                });
                return;
            }

            var sqlServer = new SqlServer
            {
                ServiceInstance = serviceInstanceRow
            };


            var result = await sqlServer.CreateiToolDatabase(new InstallOptions
            {
                IP = serviceInstanceRow.NodeIP,
                databaseType = string.Join(',', selected.Select(item => item.Value)),
                Port = serviceInstanceRow.Port,
                Password = serviceInstanceRow.Password
            });

            if (result.Item1)
            {
                serviceInstanceRow.Type = string.Join(',', ckeckAllOptions.Where(item => item.Checked).Select(item => item.Value));
                this.visibleCreateDatabase = false;

                var task = notice.Success(new NotificationConfig
                {
                    Message = "操作成功",
                    Description = result.Item2
                });
            }
            else
            {
                var task = notice.Error(new NotificationConfig
                {
                    Message = "操作失败",
                    Description = result.Item2
                });
            }

            serviceInstanceRow.Status = 2;
            base.StateHasChanged();

        });

    }

    private async Task OperationConfrim(Node node, ServiceInstance service, int type, string dbName = null)
    {
        if (type == 6)
        {
            this.visibleCreateDatabase = true;

            foreach (var item in service.Type?.Split(','))
            {
                foreach (var check in ckeckAllOptions)
                {
                    if (check.Value == item)
                    {
                        check.Disabled = true;
                        check.Checked = true;
                        break;
                    }
                    else if (!check.Disabled)
                    {
                        check.Checked = false;
                    }
                }
            }

            this.serviceInstanceRow = service;
            return;
        }


        await base.InvokeAsync(async () =>
        {

            string content = string.Empty;

            AbstractServer abstractServer = new SqlServer { ServiceInstance = service };

            if (service.Process == "iToolService")
            {
                abstractServer = new iToolService { ServiceInstance = service };
            }
            else if (service.Process == "iToolClient")
            {
                abstractServer = new iToolClient { ServiceInstance = service };
            }

            var options = new InstallOptions
            {
                IP = service.NodeIP,
                Title = service.Title,
                Port = service.Port,
                Password = service.Password
            };

            switch (type)
            {
                case 1:
                // start
                _loading = true;
                    var result = await abstractServer.Start(options);
                    if (result.Item1)
                    {
                        var task = notice.Success(new NotificationConfig
                        {
                            Message = "操作成功",
                            Description = result.Item2
                        });
                    }
                    else
                    {
                        var task = notice.Error(new NotificationConfig
                        {
                            Message = "操作失败",
                            Description = result.Item2
                        });
                    }
                    _loading = false;
                    base.StateHasChanged();
                    return;

                case 2:
                    content = "Are you sure you want to Backup ?";
                    break;
                case 3:
                    content = "Are you sure you want to restart ?";
                    break;
                case 4:
                    content = "Are you sure you want to stop ?";
                    break;
                case 5:
                    content = "Are you sure you want to clear and delete ?";
                    break;
                case 7:
                    content = $"Are you sure you want to drop {dbName} ?";
                    break;
            }

            var title = "Warning";
            var confirmResult =
                await _confirmService.Show(
                    content,
                    title,
                    ConfirmButtons.YesNo,
                    ConfirmIcon.Warning
                );

            if (confirmResult.ToString() == "Yes")
            {
                (bool, string) result = (false, string.Empty);
                _loading = true;
                base.StateHasChanged();

                switch (type)
                {
                    case 2:
                        result = await abstractServer.Backup(options);
                        break;
                    case 3:
                        result = await abstractServer.ReStart(options);
                        break;
                    case 4:
                        result = await abstractServer.Stop(options);
                        break;
                    case 5:
                        result = await abstractServer.Remove(options);
                        break;
                    case 7:
                        result = await (abstractServer as SqlServer).DropiToolDatabase(options, dbName);
                        break;
                }

                if (result.Item1)
                {
                    if (type == 5)
                    {
                        node.ServiceInstances.Remove(service);
                    }
                    var task = notice.Success(new NotificationConfig
                    {
                        Message = "操作成功",
                        Description = result.Item2
                    });
                }
                else
                {
                    var task = notice.Error(new NotificationConfig
                    {
                        Message = "操作失败",
                        Description = result.Item2
                    });
                }

                _loading = false;

                base.StateHasChanged();

            }
        });

    }

    void OnRowExpand(RowData<Node> rowData)
    {
        if (rowData.Data.ServiceInstances?.Count > 0)
        {
            return;
        }

        // rowData.Data.ServiceInstances =  动态加载当前内容

        // StateHasChanged();
    }

    void MessageCloseTriggerCreate(string message)
    {

        AbstractServer instance = new SqlServer();
        int typeIndex = 0;

        if (message == "Not SqlServer > Function")
        {
            typeIndex = 1;
            this.visible = false;
            return;
        }
        else if (message == "Not SqlServer > iToolBase")
        {
            typeIndex = 3;
            this.visible = false;
            return;
        }
        else if (message == "Not SqlServer > Logger")
        {
            typeIndex = 0;
            this.visible = false;
            return;
        }
        else if (message == "Not SqlServer > Message")
        {
            typeIndex = 2;
            this.visible = false;
            return;
        }
        //else if (message == "Not RabbitMQ")
        //{
        //    instance = new RabbitMQ();
        //}
        //else if (message == "Not Redis")
        //{
        //    instance = new Redis();
        //}
        else if (message == "Not MongoDB")
        {
            instance = new MongoDB();
        }
        else if (message == "Not Elasticsearch")
        {
            instance = new Elasticsearch();
        }
        else
        {
            return;
        }

        this.CreateInstInstance(instance, typeIndex);
    }

}


<style>
    .ant-form-item-label {
        flex: 0 0 130px !important;
    }

    .ant-col-offset-8 {
        margin-left: 130px;
    }

    .add-icon {
        border: 1px solid #abaaaa;
        color: #797777;
        border-radius: 50%;
        width: 24px;
        height: 24px;
        text-align: center;
        line-height: 24px;
        margin-top: 4px;
        margin-left: 20px;
        padding-right: 1px;
    }

    .ant-btn {
        font-size: 12px;
        padding: 2px 10px;
        height: auto;
    }

    tr.ant-table-expanded-row > td {
        background: #4e9c25;
        background-image: linear-gradient(top,rgb(250 250 250),#4e9c25);
        background-image: -webkit-linear-gradient(top,rgb(250 250 250),#4e9c25);
        background-image: -o-linear-gradient(top,rgb(250 250 250),#4e9c25);
        /*background-image: -ms-linear-gradient(top,rgb(250 250 250),#4e9c25);*/
        background-image: linear-gradient(top,rgb(250 250 250),#4e9c25);
    }


        tr.ant-table-expanded-row > td:hover {
            background: #4e9c25;
            background-image: linear-gradient(top,rgb(250 250 250),#4e9c25);
            background-image: -webkit-linear-gradient(top,rgb(250 250 250),#4e9c25);
            background-image: -o-linear-gradient(top,rgb(250 250 250),#4e9c25);
            /*background-image: -ms-linear-gradient(top,rgb(250 250 250),#4e9c25);*/
            background-image: linear-gradient(top,rgb(250 250 250),#4e9c25);
        }

    .ant-progress-circle-gradient {
        width: 60px !important;
        height: 60px !important;
        font-size: 14px !important;
    }

    .ant-table-thead > tr > th {
        text-align: center;
    }

    .ExpandTemplateTable .ant-table-thead > tr > th {
        text-align: left;
    }

    .ant-checkbox-wrapper {
        width: 100%;
        margin-top: 10px;
        margin-left: 8px;
    }
</style>
